// Copyright 2023 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef _QUEUE_MODULES_H_
#define _QUEUE_MODULES_H_

#include <sys/epoll.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/prctl.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <thread>
#include <mutex>
#include <map>
#include <vector>

#include "TheadSafeQueue.h"
#include "securec.h"

namespace master {

const static uint32_t MAX_QUEUE_DATA_LEN = 10240;

    typedef enum {
        QUEUE_READ,
        QUEUE_DEAL,
        QUEUE_WRITE,
    } QueueType;

    typedef struct ReadDataS {
        int inFd;
        std::string requestId;
    } ReadDataT;

    typedef struct DealDataS {
        int fd;
        int cmdCtl;
        std::string requestId;
        uint32_t bufLen;
        std::shared_ptr<uint8_t> pClientRData;
        
    } DealDataT;

    typedef struct WriteDataS {
        int fd;
        int cmdCtl;
        std::string requestId;
        uint32_t bufLen;
        std::shared_ptr<uint8_t> pClientWData;

        WriteDataS &operator=(WriteDataS &src) {
            fd = src.fd;
            cmdCtl = src.cmdCtl;
            requestId = src.requestId;
            bufLen = src.bufLen;
            pClientWData = src.pClientWData;
            return *this;
        }
        
    } WriteDataT;

class QueueModules {

public:
    QueueModules() { }    
    ~QueueModules()     = default;

private:
    int PushReadFd(uint8_t *inData, uint32_t inLen, int fd, std::string requestId);

    int PushDealData(uint8_t *inData, uint32_t inLen, 
                        uint16_t cmdCtl, int fd, std::string requestId);

    int PushWriteData(uint8_t *inData, uint32_t inLen, 
                      uint16_t cmdCtl, int fd, std::string requestId);

    int PopReadFd(uint8_t *outData, uint32_t *outLen, int *fd, std::string &requestId);

    int PopDealData(uint8_t *outData, uint32_t *outLen, 
                       uint16_t *cmdCtl, int *fd, std::string &requestId);

    int PopWriteData(uint8_t *outData, uint32_t *outLen, 
                     uint16_t *cmdCtl, int *fd, std::string &requestId);

public:
    int GetDealQueueSize();
    int Push(QueueType queueType, uint8_t *inData, 
        uint32_t inLen, uint16_t cmdCtl, int fd, std::string requestId);

    int Pop(QueueType queueType, uint8_t *outData, uint32_t *outLen, 
        uint16_t *cmdCtl, int *fd, std::string &requestId);

public:
    threadsafe_queue<std::shared_ptr<ReadDataT>> readQueue;
    threadsafe_queue<std::shared_ptr<DealDataT>> dealQueue;
    threadsafe_queue<std::shared_ptr<WriteDataT>> writeQueue;
};
};

#endif